from datetime import datetime
from decimal import Decimal
from pydantic import BaseModel, Field, validator
from typing import Optional

class AsphaltMixingDataBase(BaseModel):
    source: Optional[str] = Field(None, max_length=50)
    mpNum: str = Field(..., max_length=50, alias="mp_num")
    colTime: Optional[datetime] = Field(None, alias="col_time")
    remark1: Optional[str] = Field(None, max_length=50, alias="remark_1")
    isP: Optional[int] = Field(None, alias="is_p")
    formula: Optional[str] = Field(None, max_length=50)
    lq: Optional[Decimal] = None
    dischargeTime: Optional[datetime] = Field(None, alias="discharge_time")
    stirTime: Optional[Decimal] = Field(None, alias="stir_time")
    lqTem: Optional[Decimal] = Field(None, alias="lq_tem")
    stoneTem: Optional[Decimal] = Field(None, alias="stone_tem")
    production: Optional[Decimal] = None
    ar: Optional[Decimal] = None
    stone1: Optional[Decimal] = Field(None, alias="stone_1")
    stone2: Optional[Decimal] = Field(None, alias="stone_2")
    stone3: Optional[Decimal] = Field(None, alias="stone_3")
    stone4: Optional[Decimal] = Field(None, alias="stone_4")
    stone5: Optional[Decimal] = Field(None, alias="stone_5")
    stone6: Optional[Decimal] = Field(None, alias="stone_6")
    stone7: Optional[Decimal] = Field(None, alias="stone_7")
    ore1: Optional[Decimal] = Field(None, alias="ore_1")
    ore2: Optional[Decimal] = Field(None, alias="ore_2")
    additive: Optional[Decimal] = None
    thAr: Optional[Decimal] = Field(None, alias="th_ar")
    thStone1: Optional[Decimal] = Field(None, alias="th_stone_1")
    thStone2: Optional[Decimal] = Field(None, alias="th_stone_2")
    thStone3: Optional[Decimal] = Field(None, alias="th_stone_3")
    thStone4: Optional[Decimal] = Field(None, alias="th_stone_4")
    thStone5: Optional[Decimal] = Field(None, alias="th_stone_5")
    thStone6: Optional[Decimal] = Field(None, alias="th_stone_6")
    thStone7: Optional[Decimal] = Field(None, alias="th_stone_7")
    thOre1: Optional[Decimal] = Field(None, alias="th_ore_1")
    thOre2: Optional[Decimal] = Field(None, alias="th_ore_2")
    thLq: Optional[Decimal] = Field(None, alias="th_lq")
    thAdditive: Optional[Decimal] = Field(None, alias="th_additive")
    dischargeTem: Optional[Decimal] = Field(None, alias="discharge_tem")
    createTime: Optional[datetime] = Field(None, alias="create_time")
    updateTime: Optional[datetime] = Field(None, alias="update_time")

    @validator('*')
    def empty_str_to_none(cls, v):
        if isinstance(v, str) and v.strip() == '':
            return None
        return v

    @validator('stone1', 'stone2', 'stone3', 'stone4', 'stone5', 'stone6', 'stone7',
              'ore1', 'ore2', 'lq', 'additive', 'thAr', 'thStone1', 'thStone2',
              'thStone3', 'thStone4', 'thStone5', 'thStone6', 'thStone7',
              'thOre1', 'thOre2', 'thLq', 'thAdditive', 'dischargeTem',
              'stirTime', 'lqTem', 'stoneTem', 'production', 'ar', pre=True)
    def convert_decimal(cls, v):
        if v is None or (isinstance(v, str) and v.strip() == ''):
            return None
        try:
            return Decimal(str(v))
        except (TypeError, ValueError):
            return None

    @validator('colTime', 'dischargeTime', 'createTime', 'updateTime', pre=True)
    def parse_datetime(cls, v):
        if v is None or (isinstance(v, str) and v.strip() == ''):
            return None
        if isinstance(v, datetime):
            return v
        try:
            # 尝试多种日期时间格式
            for fmt in ["%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d"]:
                try:
                    return datetime.strptime(v, fmt)
                except ValueError:
                    continue
            return None
        except Exception:
            return None

    class Config:
        from_attributes = True
        populate_by_name = True  # 允许通过别名访问字段
        json_encoders = {
            datetime: lambda v: v.strftime("%Y-%m-%d %H:%M:%S") if v else None,
            Decimal: lambda v: str(v) if v is not None else None
        }

class AsphaltMixingDataCreate(AsphaltMixingDataBase):
    pass

class AsphaltMixingDataInDB(AsphaltMixingDataBase):
    id: int

    class Config:
        from_attributes = True
        populate_by_name = True  # 允许通过别名访问字段